#ifndef _RIL_DEVICE_H_
#define _RIL_DEVICE_H_

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "nat.h"
#include "nsocket.h"
/* Public typedef ------------------------------------------------------------*/

enum RilPin
{
	RIL_PIN_STARTUP,
	RIL_PIN_SHUTDOWN,
	RIL_PIN_RESET
};

/************************************
	Ril Device Structs
  ***********************************/
struct RilDevice;

struct RilDeviceStatus
{
    char    imei[16];
    char    imsi[16];
    int8_t  csq;
    int8_t  simStatus;
};

struct RilOperations
{
    int (*startUp)(struct RilDevice *device);
    int (*sleep)(struct RilDevice *device);
    int (*shutDown)(struct RilDevice *device);
    int (*init)(struct RilDevice *device);
    int (*reset)(struct RilDevice *device, bool usePin);
    int (*pdp)(struct RilDevice *device);
    struct OpsSocket{
		int (*release)(struct RilDevice *device, struct Socket *socket);
        int (*connect)(struct RilDevice *device, struct Socket *socket, const struct sockaddr *name, socklen_t namelen);
        int (*disconnect)(struct RilDevice *device, struct Socket *socket);
        int (*send)(struct RilDevice *device, struct Socket *socket, void *data, size_t size, int flags);
		int (*sendto)(struct RilDevice *device, struct Socket *socket, void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen);
        int (*recv)(struct RilDevice *device, struct Socket *socket, void *mem, size_t size, int flags);
		int (*recvfrom)(struct RilDevice *device, struct Socket *socket, void *mem, size_t size, int flags, struct sockaddr *from, socklen_t *fromlen);
    }opsSocket;
};

struct RilDeviceDriver
{
    char                        	*name;              // device name
    const struct RilOperations  	*ops;               // device operation , include control and socket 
    const struct Nat            	*at;                //
	const struct RilDeviceStatus  	*status;
};

struct RilDeviceConfig
{
    int reserve;
};

struct RilDevice
{
	struct NatAdapter       *adapter;
	struct RilDeviceDriver  *driver;
	struct RilDeviceConfig  *config;
};

/* Public variables ----------------------------------------------------------*/
/* Public define -------------------------------------------------------------*/
/* Public macro --------------------------------------------------------------*/

#define RIL_MODULE_INSTALL(devName)	        \
    const struct RilDeviceDriver rilDeviceDriver##devName __attribute__((used, __section__("ril.device.1"))) = {   \
        .name = #devName,                      	\
        .ops = &##devName##Ops,                	\
        .at = &##devName##Nat,      		 	\
		.status =  &##devName##Status};

/* Public function prototypes ------------------------------------------------*/
int RilDevice_ExecuteCommand(struct RilDevice *dev, int32_t timeout, char *response, char *format, ...);

int Ril_Init(struct NatAdapter *adapter, struct RilDeviceConfig *config, char *driverName);
void RilDevice_ClearMessages(void);
int RilDevice_ATTest(void);
int RilDevice_Init(void);
int RilDevice_StartUp(void);
int RilDevice_ShutDown(void);
int RilDevice_Reset(bool useResetPin);
int RilDevice_Pdp(void);
		
int RilDevice_SendRaw(struct RilDevice *dev, int32_t waitTime, char* response, uint8_t *packet, size_t size);
int RilDevice_Release(struct RilDevice *device, struct Socket *socket);	
int RilDevice_Connect(struct RilDevice *device, struct Socket *socket, const struct sockaddr *name, socklen_t namelen);
int RilDevice_Disconnect(struct RilDevice *device, struct Socket *socket);
int RilDevice_Send(struct RilDevice *device, struct Socket *socket, void *data, size_t size, int flags);
int RilDevice_SendTo(struct RilDevice *device, struct Socket *socket, void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen);
int RilDevice_Recv(struct RilDevice *device, struct Socket *socket, void *mem, size_t size, int flags);
int RilDevice_RecvFrom(struct RilDevice *device, struct Socket *socket, void *mem, size_t size, int flags, struct sockaddr *from, socklen_t *fromlen);
		
char* RilDevice_Imei(void);
char* RilDevice_Imsi(void);
#endif
